package cn.xeyuan.redis.lock;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.stereotype.Component;

@Component
public class RedisLock {
    @Autowired
    private StringRedisConnection stringRedisConnection;
    public void lookDemo(String lookKey, int timeOut) throws InterruptedException {
        boolean status = false;
        while (!status) {
            long nowTime = System.currentTimeMillis() / 1000;
            long lookTimeOut = nowTime + timeOut + 1;
            status = stringRedisConnection.setNX(lookKey,String.valueOf(lookTimeOut));
            System.out.println("开始获得key-------<"+status+">");
            if (status) {//获得锁成功
                break;
            } else {
                //获得锁的时间，判断该锁是否超时了还未解锁
                long lookTime = Long.valueOf(stringRedisConnection.get(lookKey));
                //当前锁已经超时了
                if (nowTime > lookTime) {
//                    从新设置锁的超时时间
//                    由于 GETSET 操作在设置键的值的同时，还会返回键的旧值，通过比较键 lookKey 的旧值是否小于当前时间，可以判断进程是否已获得锁
                    long oldLookTime = Long.valueOf(stringRedisConnection.getSet(lookKey,String.valueOf(lookTimeOut)));
                    if (nowTime > oldLookTime) {
                        System.out.println("重新设置超时时间，并获得锁");
                        break;
                    }
                }
                Thread.sleep(1);
                System.out.println("获得key失败，重新获得-------<"+status+">");
            }
        }
        System.out.println("开始休眠10s-------<"+status+">");
        //休眠10s
        Thread.sleep(1000*10);
        System.out.println("休眠结束，删除key");
        //删除key
        stringRedisConnection.del(lookKey);

    }
}
